import { ObjType } from '@/@type'
import config from '@/config'
import store from '@/store'
import dayjs from 'dayjs'
const { labelKey, valKey } = config
const qs = require('qs')
import Qrcode from '@/utils/qrcode'
// 获取基础url 地址

export const qrcodeCreate = (content) => {
  // 生成二维码
  return Qrcode.drawImg(content, {
    typeNumber: 3, // 码点大小 1-40，数字越大，码点越小，二维码会显得越密集
    errorCorrectLevel: 'H' // 纠错等级 H等级最高(30%)
  })
}
// #ifdef H5
export const getBaseUrl = () => {
  const location = window.location
  return location.origin + location.pathname
}
// 获取某一个值
export const getWidowValue = (key, target = window) => {
  return new Promise((resolve, reject) => {
    function getStatus(resolve) {
      setTimeout(() => {
        if (target[key]) {
          resolve(target[key])
        } else {
          getStatus(resolve)
        }
      }, 200)
    }
    getStatus(resolve)
  })
}
// #endif
export const sleep = (time) =>
  new Promise((resolve) => {
    setTimeout(resolve, time)
  })
export function isString(val) {
  return typeof val === 'string'
}

export function obj2Param(obj = {}) {
  return qs.stringify(obj)
}

export const deep = (obj: ObjType) => JSON.parse(JSON.stringify(obj))

// 去重
export const deDup = (array: any[]) => {
  return [...new Set([...array])]
}

export const deDupArray = (array: any[], key = 'id') => {
  const obj = {}
  const result: any[] = []
  array = deep(array)
  const len = array.length
  for (let i = len; i--; ) {
    const item = array[i]
    if (!obj[item[key]] && item[key]) {
      result.unshift(item)
      obj[item[key]] = true
    }
  }
  return result
}

export const getModelDataByKey = (dataKey) => {
  const baseData = store.getters.baseData || {}
  return baseData[dataKey] || []
}

export const getModelValByKey = (v, dataKey, vKey: string | true = labelKey, defaultVal: any = '-') => {
  // debugger
  const dataList = getModelDataByKey(dataKey)
  const item = dataList.find((i) => i[valKey] === v + '') || {}
  if (vKey === true) {
    return item
  }
  return item[vKey] ?? defaultVal
}

/**
 * 判断当前时间是否在指定日期范围内
 * @Date: 2022-11-24 11:45
 * @param date [beginDateStr] [开始日期] yyyy-MM-dd
 * @param date [endDateStr] [结束日期] yyyy-MM-dd
 * @return Boolean
 */
export const isDuringDate = (beginDateStr, endDateStr) => {
  const curDate = new Date()
  const beginDate = new Date(beginDateStr.replace(/-/g, '/'))
  const endDate = new Date(endDateStr.replace(/-/g, '/'))
  console.log(curDate, beginDate, endDate)
  if (curDate >= beginDate && curDate <= endDate) {
    return true
  }
  return false
}
// 计算今天明天 周几
export const getDateDesc = (v, type = 1) => {
  const format = 'YYYY-MM-DD'
  const date = dayjs(v).format(format)
  const today = dayjs(new Date()).format(format)
  const tomorrow = dayjs(new Date()).add(1, 'days').format(format)
  if (type === 1) {
    if (date === today) {
      return '今天'
    }
    if (date === tomorrow) {
      return '明天'
    }
  }
  const desc = '周'
  const weekday = ['日', '一', '二', '三', '四', '五', '六']
  const day = new Date(date).getDay()
  if (type === 1) {
    return desc + weekday[day]
  } else {
    return {
      week: weekday[day],
      isNow: date === today
    }
  }
}
// 计算今天 明 后天
export const dateDescfrt = (v, frt = 'MM-DD') => {
  const format = 'YYYY-MM-DD'
  const date = dayjs(v).format(format)
  const today = dayjs(new Date()).format(format)
  const tomorrow = dayjs(new Date()).add(1, 'days').format(format)

  if (date === today) {
    return '今天'
  }
  if (date === tomorrow) {
    return '明天'
  }
  return dayjs(v).format(frt)
}
export const dateFmt = (date, fmt = 'YYYY-MM-DD') => {
  return dayjs(date).format(fmt)
}
export const getDateWeek = (v) => {
  return getDateDesc(v) + ' ' + dateFmt(v, 'MM月DD日')
}
//获取相对不重复的随机数
export const getRandom = () => {
  return +new Date() + Math.random().toString().slice(3, 7)
}

// 数字列表如果是 NAN 时采取默认值
export const isNaNStr = (v: any, str = 0): number => {
  v = (v + '').replace(/\,/g, '')
  v = parseFloat(v)
  if (isNaN(v)) {
    return str
  }
  return v
}

// 获取数组中最小值
export const getMin = (array: any[]) => {
  const arr = array.map((i) => isNaNStr(i))
  return Math.min(...arr)
}

// 获取数组中最大值
export const getMax = (array: any[]) => {
  const arr = array.map((i) => isNaNStr(i))
  return Math.max(...arr)
}

// 小数点保留
export const toFixed = (v, num = 2) => {
  v = isNaNStr(v)
  const value = Number(v)
  const res = parseFloat(value.toFixed(num))
  return res
}

// 防抖模式（只执行设定时间内的最后一次）
export const debounce = (fn: any, args: any[] = [], that: any = null, time = 300) => {
  fn._debounceId && clearTimeout(fn._debounceId)
  fn._debounceId = setTimeout(function () {
    // 执行函数
    fn.apply(that, args)
  }, time)
}

// // 节流模式（间隔设定时间执行一次）
// export const throttle = (
//   fn,
//   args: any[] = [],
//   that: any = null,
//   time = 300
// ) => {
//   let preTime = Date.now()
//   return function () {
//     const nowTime = Date.now()
//     // 如果两次时间间隔超过了指定时间，则执行函数。
//     if (nowTime - preTime >= time) {
//       preTime = Date.now()
//       return fn.apply(that, args)
//     }
//   }
// }
// 节流模式 （业务逻辑只执行最后一次）
export const throttle = (fn, args: any[] = [], that: any = null, time = 300) => {
  fn._throttleID && clearTimeout(fn._throttleID)
  fn._throttleID = setTimeout(function () {
    // 执行函数
    fn.apply(that, args)
  }, time)
}
export function getSlotRef<T = any>(that, name) {
  let refInfo
  // #ifdef MP-ALIPAY
  refInfo = that.$children[0].$refs[name]
  // #endif

  // #ifndef MP-ALIPAY
  refInfo = that.$refs[name]
  // #endif

  return refInfo as T
}

export function splitArr(array: any[], num: number) {
  const list = [] as any[]
  for (let i = 0; i < array.length; i += num) {
    list.push(array.slice(i, i + num))
  }
  return list
}
export function getOssImg(fileName, suffix = 'png') {
  let src = ''
  if (fileName) {
    src = config.ossUrl + '/' + fileName + '.' + suffix
  }
  return src
}
export function getOssImg2(fileName) {
  let src = ''
  if (fileName) {
    src = config.ossUrl + '/' + fileName
  }
  return src
}
export const eachOwn = (obj, fn) => {
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      fn(obj[key], key, obj)
    }
  }
}
// 转译换行
export const toHtml = (v) => {
  if (!v) {
    return ''
  }
  v = v + ''
  // v = v.replace(/\\n/gm, '<br>')
  v = v.replace(/\n|\\n|↵/gm, '<br>')
  // v = v.replace(/↵/gm, '<br>')
  return v || ''
}
// 经纬度计算距离 单位 千米
export const getDistance = (lat1, lng1, lat2, lng2) => {
  if (!(lat1 && lng1 && lat2 && lng2)) {
    return -1
  }
  lat1 = +lat1
  lng1 = +lng1
  lat2 = +lat2
  lng2 = +lng2
  const radLat1 = (lat1 * Math.PI) / 180.0
  const radLat2 = (lat2 * Math.PI) / 180.0
  const a = radLat1 - radLat2
  const b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0
  let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)))
  s = s * 6378.137 // EARTH_RADIUS;
  s = Math.round(s * 10000) / 10000
  return s
}

export const getDistanceTxt = (v) => {
  v = +v
  if (isNaN(v)) {
    return -1
  }
  if (v === -1) {
    return ''
  }
  if (v < 1) {
    return (v * 1000).toFixed(0) + 'm'
  } else if (v > 100) {
    return '>100km'
  } else {
    return v.toFixed(1) + 'km'
  }
}
// 百分比
export const percent = (v) => {
  v = isNaNStr(v)
  return (v * 1000) / 10 + '%' // 处理精度问题 0.07*100
}
// key down 降序  up 生序
export const sortList = (list, property, key = 'up') => {
  const array = deep(list)
  for (let len = array.length; len--; ) {
    array[len].oldIndex = len
  }
  array.sort((a, b) => {
    if (key === 'down') {
      return b[property] - a[property] || a.oldIndex - b.oldIndex
    }
    return a[property] - b[property] || a.oldIndex - b.oldIndex
  })
  return array
}
// 数组转map(分类)
export const arrayToMap = (arr, filed) => {
  const map = {}
  arr.forEach((item, index) => {
    item.index = index
    if (item[filed]) {
      if (!map[item[filed]]) {
        map[item[filed]] = item
      } else {
        // 有重复覆盖
        map[item[filed]] = item
      }
    }
  })
  return map
}
// 时间转化格式
export const getDateFormat = (v, format = 'YYYY-MM-DD') => {
  console.log(v, format)
  return dayjs(v).format(format)
}
export const formatRichText = (html) => {
  let newContent = html.replace(/<img[^>]*>/gi, function (match, capture) {
    match = match.replace(/style="[^"]+"/gi, '').replace(/style='[^']+'/gi, '')
    match = match.replace(/width="[^"]+"/gi, '').replace(/width='[^']+'/gi, '')
    match = match.replace(/height="[^"]+"/gi, '').replace(/height='[^']+'/gi, '')
    return match
  })
  newContent = newContent.replace(/style="[^"]+"/gi, function (match, capture) {
    match = match.replace(/width:[^;]+;/gi, 'width:100%;').replace(/width:[^;]+;/gi, 'width:100%;')
    return match
  })
  newContent = newContent.replace(/<br[^>]*\/>/gi, '')
  newContent = newContent.replace(/\<img/gi, '<img style="width:100%;height:auto;display:inline-block;margin:10rpx auto;"')
  return toHtml(newContent)
}
export const encode = (query: any) => {
  return encodeURIComponent(JSON.stringify(query))
}
export const decode = (query: any) => {
  return JSON.parse(decodeURIComponent(query))
}
export const calcNumSum = (array = []) => {
  const t = array.reduce((total, num) => {
    return total + isNaNStr(num)
  }, 0)
  return t
}
export const objIsNull = (v: any) => {
  for (const key in v) {
    return false
  }
  return true
}
// 数字向下取整
export const floor = (v) => {
  const num = isNaNStr(v)
  return Math.floor(num)
}
// 字符串拼接
export const join = (v, str, position = 'right') => {
  if (position === 'right') {
    return v + '' + str
  } else if (position === 'left') {
    return str + '' + v
  }
}
// 数组对象价格累加
export const arrayCalc = (array, priceKey, numKey) => {
  const len = array.length || 0
  let sum = 0
  for (let i = len; i--; ) {
    const item = array[i]
    const num = numKey ? item[numKey] : 1
    const price = priceKey ? item[priceKey] : item
    const value = isNaNStr(num) * isNaNStr(price)
    sum = sum + value
  }
  return sum
}
export function param2Obj(url) {
  // 路径参数转对象

  let search = url.split('?')[1]
  if (url.split('?')[2]) {
    search = url.split('?')[2]
  }
  if (!search) {
    return {}
  }
  const query = search.replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"').replace(/\+/g, ' ')
  return JSON.parse('{"' + decodeURIComponent(query) + '"}')
}
// 动态加载 js 文件
export const createScript = (obj = {}, el = 'head') => {
  const jsapi = document.createElement('script')
  for (const i in obj) {
    jsapi[i] = obj[i]
  }
  document[el].appendChild(jsapi)
  return new Promise((resolve: any) => {
    jsapi.onload = () => {
      resolve()
    }
  })
}
export const createTitle = (title: any) => {
  // #ifdef H5
  setTimeout(() => {
    uni.setNavigationBarTitle({
      title
    })
  }, 500)

  // #endif
}
export default {
  //  #ifdef H5
  getWidowValue,
  // #endif
  createTitle,
  isString,
  obj2Param,
  deep,
  deDup,
  deDupArray,
  getModelDataByKey,
  getModelValByKey,
  percent,
  dateFmt,
  getRandom,
  join,
  isNaNStr,
  getMin,
  getMax,
  toFixed,
  debounce,
  throttle,
  getSlotRef,
  sleep,
  splitArr,
  getOssImg,
  eachOwn,
  objIsNull,
  floor,
  toHtml,
  getDistance,
  sortList,
  getDateDesc,
  isDuringDate,
  arrayToMap,
  getDateFormat,
  dateDescfrt,
  formatRichText,
  encode,
  decode,
  calcNumSum,
  arrayCalc,
  getDateWeek,
  param2Obj,
  createScript
}
